﻿// -------------------------------------------------------------------------------------------------------------------------------
// <copyright file="TestSubtractFactorMatrix.cs" company="Exul">
//     Copyright (c) Exul. All rights reserved.
// </copyright>
// <author>
//     Exul
// </author>
// -------------------------------------------------------------------------------------------------------------------------------

namespace ExulLibrary.Mathematics.LinearAlgebra.Sequential.Tests.MatrixExtensionsTest.DoubleExtensions
{
    #region Usings

    using ExulLibrary.Mathematics.LinearAlgebra.Sequential.DoubleExtensions;

    using NUnit.Framework;

    #endregion

    /// <summary>
    ///     Test suite for <see cref="MatrixExtensions.Subtract(Matrix{double},double,Matrix{double})"/>.
    /// </summary>
    [TestFixture]
    [Category("ExulLibrary.Mathematics.LinearAlgebra.Sequential.DoubleExtensions.MatrixExtensions")]
    public sealed class TestSubtractFactorMatrix
    {
        #region Methods

        #region public

        /// <summary>
        ///     Tests the method when matrix has <see cref="CMDenseMatrix{T}"/> type.
        /// </summary>
        [Test]
        public void WhenMatrixHasCMDenseMatrixType()
        {
            // Arrange
            var minuendData = new[]
                              {
                                  new double[] { 10, 15 },
                                  new double[] { 20, 25 },
                                  new double[] { 30, 35 }
                              };
            var minuend = new CMDenseMatrix<double>(minuendData);
            var subtrahendData = new[]
                                 {
                                     new double[] { 1, 2 },
                                     new double[] { 3, 4 },
                                     new double[] { 5, 6 }
                                 };
            var subtrahend = new CMDenseMatrix<double>(subtrahendData);
            var expected = new[]
                           {
                               new double[] { 19, 28 },
                               new double[] { 37, 46 },
                               new double[] { 55, 64 }
                           };

            // Act
            MatrixExtensions.Subtract(minuend, 2, subtrahend);

            // Assert
            Assert.That(minuend.Values, Is.EquivalentTo(expected));
        }

        /// <summary>
        ///     Tests the method when matrix has <see cref="CMFlattenDenseMatrix{T}"/> type.
        /// </summary>
        [Test]
        public void WhenMatrixHasCMFlattenDenseMatrixType()
        {
            // Arrange
            var minuendData = new double[]
                              {
                                  10, 15,
                                  20, 25,
                                  30, 35
                              };
            var minuend = new CMFlattenDenseMatrix<double>(2, 3, minuendData);
            var subtrahendData = new double[]
                                 {
                                     1, 2,
                                     3, 4,
                                     5, 6
                                 };
            var subtrahend = new CMFlattenDenseMatrix<double>(2, 3, subtrahendData);
            var expected = new[]
                           {
                               19, 28,
                               37, 46,
                               55, 64
                           };

            // Act
            MatrixExtensions.Subtract(minuend, 2, subtrahend);

            // Assert
            Assert.That(minuend.Values, Is.EquivalentTo(expected));
        }

        /// <summary>
        ///     Tests the method when matrix has <see cref="DenseSymmetricMatrix{T}"/> type.
        /// </summary>
        [Test]
        public void WhenMatrixHasDenseSymmetricMatrixType()
        {
            // Arrange
            var subtrahendData = new double[] { 1, 2, 3 };
            var subtrahend = new DenseSymmetricMatrix<double>(subtrahendData);
            var minuendData = new double[] { 10, 20, 30 };
            var minuend = new DenseSymmetricMatrix<double>(minuendData);
            var expectedResult = new double[] { 19, 38, 57 };

            // Act
            MatrixExtensions.Subtract(minuend, 2, subtrahend);

            // Assert
            Assert.That(minuend.Values, Is.EquivalentTo(expectedResult));
        }

        /// <summary>
        ///     Tests the method when matrix has <see cref="RMDenseMatrix{T}"/> type.
        /// </summary>
        [Test]
        public void WhenMatrixHasRMDenseMatrixType()
        {
            // Arrange
            var minuendData = new[]
                              {
                                  new double[] { 10, 15, 20 },
                                  new double[] { 25, 30, 35 }
                              };
            var minuend = new RMDenseMatrix<double>(minuendData);
            var subtrahendData = new[]
                                 {
                                     new double[] { 1, 2, 3 },
                                     new double[] { 4, 5, 6 }
                                 };
            var subtrahend = new RMDenseMatrix<double>(subtrahendData);
            var expectedResult = new[]
                                 {
                                     new double[] { 19, 28, 37 },
                                     new double[] { 46, 55, 64 }
                                 };

            // Act
            MatrixExtensions.Subtract(minuend, 2, subtrahend);

            // Assert
            Assert.That(minuend.Values, Is.EquivalentTo(expectedResult));
        }

        /// <summary>
        ///     Tests the method when matrix has <see cref="RMFlattenDenseMatrix{T}"/> type.
        /// </summary>
        [Test]
        public void WhenMatrixHasRMFlattenDenseMatrixType()
        {
            // Arrange
            var minuendData = new double[]
                              {
                                  10, 15, 20,
                                  25, 30, 35
                              };
            var minuend = new RMFlattenDenseMatrix<double>(2, 3, minuendData);
            var subtrahendData = new double[]
                                 {
                                     1, 2, 3,
                                     4, 5, 6
                                 };
            var subtrahend = new RMFlattenDenseMatrix<double>(2, 3, subtrahendData);
            var expected = new[]
                           {
                               19, 28, 37,
                               46, 55, 64
                           };

            // Act
            MatrixExtensions.Subtract(minuend, 2, subtrahend);

            // Assert
            Assert.That(minuend.Values, Is.EquivalentTo(expected));
        }

        #endregion

        #endregion
    }
}